package org.daochong.lang.security;

import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.net.ssl.X509TrustManager;

public class DynamicTrustManager implements X509TrustManager {
	public static String STORE_ALGORITHM = "JKS";
	public static String STORE_PATH = "/conf/daochong.keystore";
	public static String STORE_PASSWORD = "daochong";
	
	private File file;
	private long last = 0;
	private KeyStore keyStore;

	public DynamicTrustManager() {
		String p = System.getProperty("user.dir").trim();
		file = new File(p  + STORE_PATH);
		System.out.println(file.getPath()+":"+file.exists());
	}

	public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		if(chain==null || chain.length==0 ) throw new IllegalArgumentException();
		KeyStore keyStore = getKeyStore();
		boolean pass = false;
		try {
            for(X509Certificate certificate:chain){
                certificate.checkValidity();
                String theAlias = keyStore.getCertificateAlias(certificate);
                if(theAlias!=null)pass=true;
            }
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
		if(!pass) throw new CertificateException();
	}

	public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		if(chain==null || chain.length==0 ) throw new IllegalArgumentException();
		for(X509Certificate certificate:chain){
            certificate.checkValidity();
        }
	}

	public X509Certificate[] getAcceptedIssuers() {
		List<X509Certificate> trusts = new ArrayList<X509Certificate>();
		KeyStore keyStore = getKeyStore();
		try{
			Enumeration<String> en = keyStore.aliases();
			while(en.hasMoreElements()){
				String alias = en.nextElement();
				if(keyStore.isCertificateEntry(alias)){
					X509Certificate trust = (X509Certificate) keyStore.getCertificate(alias);
                    trusts.add(trust);
				}
			}
			return trusts.toArray(new X509Certificate[0]);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}

	private KeyStore getKeyStore() {
		if (file.lastModified() > last || this.keyStore == null) {
			try {
				this.keyStore = KeyStore.getInstance(STORE_ALGORITHM);
				this.keyStore.load(new FileInputStream(file), STORE_PASSWORD.toCharArray());
			} catch (Exception e) {
				throw new RuntimeException("load TrustManager KeyStore fail",e);
			}
		}
		return this.keyStore;
	}
}
